// Copyright 2019 The rhyme_lph Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Y [author] rhyme_lph
// F [email]  rhymelph@gmail.com
// d [github] https://github.com/rhymelph

import 'package:base_plugin/base_plugin.dart';
import 'package:finance_app/generated/l10n.dart';
import 'package:finance_app/src/common/app_colors.dart';
import 'package:finance_app/src/common/app_spaces.dart';
import 'package:finance_app/src/page/dashboard/contact/employee_contacts_page.dart';
import 'package:finance_app/src/utils/reg_exp_utils.dart';
import 'package:finance_app/src/widgets/button/add_button.dart';
import 'package:finance_app/src/widgets/button/normal_float_text_button.dart';
import 'package:finance_app/src/widgets/button/normal_float_text_white_button.dart';
import 'package:finance_app/src/widgets/list_item/list_header_item.dart';
import 'package:finance_app/src/widgets/common_app_bar.dart';
import 'package:finance_app/src/widgets/input/search_input_field.dart';
import 'package:finance_app/src/widgets/select/employee_item_radio.dart';
import 'package:flutter/material.dart';
import 'package:finance_app/src/provider/hr_payroll/employee/employee_batch_select_provider.dart';
import 'package:finance_app/src/router_gen/router_meta.dart';
import 'package:flutter_sticky_header/flutter_sticky_header.dart';
import 'package:tuple/tuple.dart';

@RouterMeta(paramName: "employeeBatchSelectPage")
class EmployeeBatchSelectPage extends StatefulWidget {
  final bool isSelectMode;
  final String pageTitle;

  const EmployeeBatchSelectPage({Key key, this.isSelectMode, this.pageTitle})
      : super(key: key);

  @override
  _EmployeeBatchSelectPageState createState() =>
      _EmployeeBatchSelectPageState();
}

class _EmployeeBatchSelectPageState extends State<EmployeeBatchSelectPage>
    with PagePresenter<EmployeeBatchSelectPage, EmployeeBatchSelectProvider> {
  String pageTitle = S.current.select_employee;

  @override
  PreferredSizeWidget get appBar => getDefaultAppBar(title: pageTitle);

  @override
  void initState() {
    if (widget.isSelectMode != null) {
      provider.isSelectMode = widget.isSelectMode;
    }
    if (widget.pageTitle != null) {
      pageTitle = widget.pageTitle;
      if (pageTitle == S.current.generate_payslip) {
        provider.isPayslip = true;
      }
    }
    super.initState();
  }

  @override
  // TODO: implement buildEmptyWidget
  Widget get buildEmptyWidget => ColoredBox(
        color: Colors.white,
        child: Stack(
          children: [
            Column(
              children: [
                AppSpaces.h20,
                SearchInputField(
                  controller: provider.searchController,
                  focusNode: provider.searchFocusNode,
                ),
                AppSpaces.h20,
                Padding(
                  padding: EdgeInsets.symmetric(
                    horizontal: getDp(23),
                  ),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      AddButton(
                        title: S.current.add_employee,
                        onTap: provider.onAddEmployee,
                      ),
                      listBuilder<int>(
                        selector: (_, __) => __.currentSelectList.length,
                        builder:
                            (BuildContext context, int value, Widget child) =>
                                PressedOpacityButton(
                          onPressed: value == 0
                              ? provider.onSelectAll
                              : provider.onDeselectAll,
                          child: Text(
                            value == 0
                                ? S.current.select_all
                                : S.current.deselect_all,
                            style: TextStyle(
                              color: aceBlueColor,
                              fontSize: getSp(16),
                              fontWeight: FontWeight.w700,
                              height: 14 / 16,
                            ),
                          ),
                        ),
                      )
                    ],
                  ),
                ),
                AppSpaces.h20,
                Expanded(
                  child: super.buildEmptyWidget,
                ),
              ],
            ),
            _buildBottomBar(),
          ],
        ),
      );

  @override
  Widget get buildWidget => ColoredBox(
        color: Colors.white,
        child: Stack(
          children: [
            Column(
              children: [
                AppSpaces.h20,
                SearchInputField(
                  controller: provider.searchController,
                  focusNode: provider.searchFocusNode,
                ),
                AppSpaces.h20,
                Padding(
                  padding: EdgeInsets.symmetric(
                    horizontal: getDp(23),
                  ),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      AddButton(
                        title: S.current.add_employee,
                        onTap: provider.onAddEmployee,
                      ),
                      listBuilder<int>(
                        selector: (_, __) => __.currentSelectList.length,
                        builder:
                            (BuildContext context, int value, Widget child) =>
                                PressedOpacityButton(
                          onPressed: value == 0
                              ? provider.onSelectAll
                              : provider.onDeselectAll,
                          child: Text(
                            value == 0
                                ? S.current.select_all
                                : S.current.deselect_all,
                            style: TextStyle(
                              color: aceBlueColor,
                              fontSize: getSp(16),
                              fontWeight: FontWeight.w700,
                              height: 14 / 16,
                            ),
                          ),
                        ),
                      )
                    ],
                  ),
                ),
                AppSpaces.h20,
                Expanded(
                  child: listBuilder<String>(
                    selector: (_, __) => __.searchController.text,
                    builder:
                        (BuildContext context, String value, Widget child) =>
                            CustomScrollView(
                      slivers: buildSearchWidget(value),
                    ),
                  ),
                ),
              ],
            ),
            _buildBottomBar(),
          ],
        ),
      );

  Widget _buildBottomBar() => Positioned(
      bottom: getDp(32) + MediaQuery.of(context).padding.bottom,
      left: 0.0,
      right: 0.0,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          NormalFloatTextWhiteButton(
            title: S.current.cancel,
            onTap: provider.onCancel,
          ),
          SizedBox(
            width: getDp(15),
          ),
          NormalFloatTextButton(
            title: S.current.select,
            onTap: provider.onSelect,
          ),
        ],
      ));

  List<Widget> buildSearchWidget(String value) {
    List<Widget> slivers;
    // if (provider.searchController.text.isNotEmpty) {
    slivers = provider.searchData.entries
        .toList()
        .where(_onSearchInputGroup)
        .map((e) => buildSliver(e.key, _onSearchInputItem(e.value)))
        .toList();
    // } else {
    //   slivers = provider.searchData.entries
    //       .toList()
    //       .map((e) => buildSliver(e.key, e.value))
    //       .toList();
    // }

    return slivers;
  }

  Widget buildSliver(String title, List<EmployeeContactEntity> data) =>
      SliverStickyHeader(
        header: buildSliverHeader(title: title),
        sliver: SliverList(
          delegate: SliverChildBuilderDelegate(
            (context, i) => buildSliverItem(data, i),
            childCount: data.length,
          ),
        ),
      );

  Widget buildSliverItem(List<EmployeeContactEntity> data, int i) {
    EmployeeContactEntity lastItemInList = provider.searchData.entries
        .toList()
        .where(_onSearchInputGroup)
        .map((e) => _onSearchInputItem(e.value))
        .toList()
        .last
        .last;

    return listBuilder<Tuple2<EmployeeContactEntity, bool>>(
      selector: (_, __) => Tuple2(
          data[i],
          __.currentSelectList.firstWhere((element) => element.id == data[i].id,
                  orElse: () => null) !=
              null),
      builder: (BuildContext context, Tuple2<EmployeeContactEntity, bool> value,
              Widget child) =>
          Column(
        children: [
          PressedOpacityButton(
            onPressed: () => provider.onSelectDetail(value.item1),
            child: EmployeeItemCheckBox(
              title: value.item1.name,
              content: value.item1.title,
              isSelect: value.item2,
              isEnable:
                  provider.isPayslip ? value.item1.canGeneratePayslip : true,
              isLastItem: data.length == i + 1,
            ),
          ),
          if (lastItemInList == value.item1) AppSpaces.h85(context),
        ],
      ),
    );
  }

  Widget buildSliverHeader({String title}) {
    final String _title = title.isEmpty ? "*" : title;
    return ListHeaderItem(
      title: _title,
    );
  }

  bool _onSearchInputGroup(
      MapEntry<String, List<EmployeeContactEntity>> element) {
    return _onSearchInputItem(element.value).length > 0;
  }

  List<EmployeeContactEntity> _onSearchInputItem(
      List<EmployeeContactEntity> element) {
    String searchInput = provider.searchController.text;
    List<EmployeeContactEntity> data = [];
    for (final item in element) {
      if (RegExpUtils.getSearchRegExp(searchInput).hasMatch(item.name)) {
        data.add(item);
      }
    }
    return data;
  }
}
